﻿using CleanArchitecture.Core;
using CleanArchitecture.Infrastructure.AutoMapper;
using CleanArchitecture.Infrastructure.Entities;
using CleanArchitecture.Infrastructure.Entities.System.Notice;
using CleanArchitecture.Infrastructure.Interfaces;
using CleanArchitecture.Infrastructure.Interfaces.AdminUsers;
using CleanArchitecture.Infrastructure.Interfaces.Notice;
using CleanArchitecture.Infrastructure.Models;
using CleanArchitecture.Infrastructure.Models.SystemManage;
using CleanArchitecture.Infrastructure.Services.SignalR;
using CleanArchitecture.Web.Backend.BackendApi;
using CleanArchitecture.Web.Factories;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace CleanArchitecture.Web.Controllers.Backend.BackendApi
{
    /// <summary>
    /// DavidLee 2019/12/27 通过继承父类Controller将Api调用与Controller渲染
    /// 前端页面分离，保持页面渲染简洁性
    /// 前端页面渲染控制器路由可在RouteProvider中注册，Api Ajax路由由Route Attribute注册
    /// </summary>
    public class BackendHomeApiController : BackendHomeController
    {
        private readonly IAdminUserModelFactory _adminuserModlFactory;
        private readonly ISystemNoticeService _systemnoticeService;
        private readonly IDateTimeHelper _datetimeHelper;
        private readonly IWorkContext _workContext;
        private readonly IHubContext<NotifyHub> _hubContext;
        public BackendHomeApiController(IAdminUserModelFactory adminUserModelFactory,
            IAdminUserService adminuserService,
            IWorkContext workContext,
            ISystemNoticeService systemnoticeService,
            IDateTimeHelper datetimeHelper,
            IHubContext<NotifyHub> hubContext,
            ISettingService settingService)
            :base(adminuserService, 
                 workContext, 
                 adminUserModelFactory,
                 settingService)
        {
            _adminuserModlFactory = adminUserModelFactory;
            _systemnoticeService = systemnoticeService;
            _datetimeHelper = datetimeHelper;
            _workContext = workContext;
            _hubContext = hubContext;
        }
        [Route(BackendApiRouteConfig.LoadSystemMenuRoute)]
        public async Task<IActionResult> LoadSystemMenu()
        {
            try
            {
                var menuLists = _adminuserModlFactory.PrepareMenuTrees();
                return SuccessJson("", menuLists);
            }
            catch (Exception ex)
            {
                return ErrorJson(ex.Message);
            }
        }

        [HttpPost(BackendApiRouteConfig.LoadSystemNoticeList)]
        public async Task<IActionResult> LoadSystemNoticeList([FromBody]SystemNoticeSearchModel searchModel)
        {
            try
            {
                var notices = _systemnoticeService.GetSystemNoticesByPage(searchModel.Page - 1, searchModel.PageSize);
                //prepare list model
                var model = new SystemNoticeListModel().PrepareToGrid(notices, () =>
                {
                    return notices.Select(notice =>
                    {
                        //fill in model values from the entity
                        var itemModel = notice.ToModel<SystemNoticeModel>();

                        itemModel.CreatedTime = _datetimeHelper.ConvertToUserTime(notice.CreatedOnTimeUtc, System.DateTimeKind.Local);
                        return itemModel;
                    });
                });
                return SuccessJson("", model);
            }
            catch(Exception ex)
            {
                return ErrorJson(ex.Message);
            }
        }

        [HttpPost(BackendApiRouteConfig.AddNewSystemNotice)]
        public async Task<IActionResult> AddNewSystemNotice([FromBody]SystemNoticeModel notice)
        {
            try
            {
                if (string.IsNullOrEmpty(notice.Title) || string.IsNullOrEmpty(notice.Text))
                    throw new NowaException(ApiResponseMessages.ArgumentCannotBeNull);
                if (notice.Title.Length > 200)
                    throw new NowaException(ApiResponseMessages.NoticeTitleLimit);
                if (notice.Text.Length > 1500)
                    throw new NowaException(ApiResponseMessages.NoticeTextLimit);
                var noticeEntity = notice.ToEntity<SystemNotice>();
                if (string.IsNullOrEmpty(noticeEntity.Publisher))
                    noticeEntity.Publisher = _workContext.CurrentAdminUser.UserName;
                noticeEntity.CreatedOnTimeUtc = DateTime.UtcNow;
                noticeEntity.IsActive = EntityEnumConfig.YesorNo.YES;
                _systemnoticeService.InsertSystemNotice(noticeEntity);
                //除了通知消息发布者不通知
                var notifyerConnectionId = new List<string>
                {
                    Request.Query["connectionId"].ToString() 
                };
                await _hubContext.Clients.AllExcept(notifyerConnectionId).SendAsync("onNewNoticeAdd", ApiResponseMessages.NewNoticeAdded);
                return SuccessJson(ApiResponseMessages.UpdateSuccess);
            }
            catch (Exception ex)
            {
                return ErrorJson(ex.Message);
            }
        }
    }
}
